package com.cykj.common.config;

import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.jwt.StpLogicJwtForSimple;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpLogic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @BelongsProject: smart_recruit_backend
 * @BelongsPackage: com.cykj.common.config
 * @Author: 蔡张君逸
 * @CreateTime: 2025-08-16 13:59
 * @Description: TODO
 * @Version: 1.0
 */
@Configuration
public class SaTokenConfiguration {
    @Autowired
    RedisTemplate<String, Object> redisTemplate;
    // Sa-Token 整合 jwt (stateless模式)
    @Bean
    public StpLogic getStpLogicJwt() {
        return new StpLogicJwtForSimple();
    }

    @Bean
    @Primary
    public SaTokenDao saRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
        return new SaTokenDao() {
            /**
             * key前缀，用于区分不同应用的缓存
             */
            private String keyPrefix = "satoken:";

            /**
             * 拼接key，添加前缀
             */
            private String getKey(String key) {
                return key;
            }

            /**
             * 获取Value，如无返空
             */
            @Override
            public String get(String key) {
                return (String) redisTemplate.opsForValue().get(getKey(key));
            }

            @Override
            public void set(String key, String value, long timeout) {
//                System.err.println(timeout);
//                System.err.println(key);
                String realKey = getKey(key);
                if (timeout == -1) {
                    // 永不过期
                    redisTemplate.opsForValue().set(realKey, value);
                } else {
                    redisTemplate.opsForValue().set(realKey, value, timeout, TimeUnit.SECONDS);
//                    System.err.println(redisTemplate.opsForValue().getOperations().getExpire(key));
                }
            }

            @Override
            public void update(String s, String s1) {

            }


            /**
             * 删除Value
             */
            @Override
            public void delete(String key) {
                redisTemplate.delete(getKey(key));
            }

            /**
             * 更新Value的过期时间 (单位: 秒)
             */
            @Override
            public void updateTimeout(String key, long timeout) {
                String realKey = getKey(key);
                if (redisTemplate.hasKey(realKey)) {
                    if (timeout == -1) {
                        // 永不过期，需要先获取原值再重新设置
                        Object value = redisTemplate.opsForValue().get(realKey);
                        redisTemplate.opsForValue().set(realKey, value);
                    } else {
                        redisTemplate.expire(realKey, timeout, TimeUnit.SECONDS);
                    }
                }
            }

            @Override
            public Object getObject(String s) {
                return null;
            }

            @Override
            public <T> T getObject(String s, Class<T> aClass) {
                return null;
            }

            @Override
            public void setObject(String s, Object o, long l) {

            }

            @Override
            public void updateObject(String s, Object o) {

            }

            @Override
            public void deleteObject(String s) {

            }

            @Override
            public long getObjectTimeout(String s) {
                return 0;
            }

            @Override
            public void updateObjectTimeout(String s, long l) {

            }

            /**
             * 获取Value的剩余存活时间 (单位: 秒)
             */
            @Override
            public long getTimeout(String key) {
                String realKey = getKey(key);
                Long expire = redisTemplate.getExpire(realKey, TimeUnit.SECONDS);
                return expire == null ? -1 : expire;
            }

            // SaSession相关方法实现

            /**
             * 获取Session
             */
            @Override
            public SaSession getSession(String sessionId) {
                String key = "session:" + sessionId;
                Object value = get(key);
                return value instanceof SaSession ? (SaSession) value : null;
            }

            @Override
            public void setSession(SaSession saSession, long l) {

            }

            @Override
            public void updateSession(SaSession saSession) {

            }

            /**
             * 删除Session
             */
            @Override
            public void deleteSession(String sessionId) {
                String key = "session:" + sessionId;
                delete(key);
            }

            /**
             * 更新Session的过期时间
             */
            @Override
            public void updateSessionTimeout(String sessionId, long timeout) {
                String key = "session:" + sessionId;
                updateTimeout(key, timeout);
            }

            @Override
            public List<String> searchData(String s, String s1, int i, int i1, boolean b) {
                return List.of();
            }

            /**
             * 获取Session的剩余存活时间
             */
            @Override
            public long getSessionTimeout(String sessionId) {
                String key = "session:" + sessionId;
                return getTimeout(key);
            }

            // getter和setter
            public String getKeyPrefix() {
                return keyPrefix;
            }

            public void setKeyPrefix(String keyPrefix) {
                this.keyPrefix = keyPrefix;
            }
        };
    }


//    @Bean
//    public SaTokenConfig saTokenConfig(RedisTemplate<String, Object> redisTemplate) {
//        SaTokenConfig config = new SaTokenConfig();
//
//        // 创建Sa-Token的Redis Dao实现类，并传入RedisTemplate
//        return config;
//    }
}